#include "alarmmodel.h"
#include "../utils/logger.h"
#include "../database/dbmanager.h"
#include <QFile>
#include <QTextStream>
#include <algorithm>

AlarmModel::AlarmModel(AlarmEngine *alarmEngine, QObject *parent)
    : QAbstractListModel(parent), m_alarmEngine(alarmEngine), m_filterMode(ShowAll), m_showActiveOnly(true), m_filterMeterId(-1)
{
    if (m_alarmEngine)
    {
        // 连接报警引擎信号
        connect(m_alarmEngine, &AlarmEngine::alarmTriggered,
                this, &AlarmModel::onAlarmTriggered);
        connect(m_alarmEngine, &AlarmEngine::alarmRecovered,
                this, &AlarmModel::onAlarmRecovered);

        // 初始加载激活的报警
        updateFilteredAlarms();
    }
}

AlarmModel::~AlarmModel()
{
}

int AlarmModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
    {
        return 0;
    }
    return m_filteredAlarms.size();
}

QVariant AlarmModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || index.row() >= m_filteredAlarms.size())
    {
        return QVariant();
    }

    const AlarmEvent &event = m_filteredAlarms.at(index.row());

    switch (role)
    {
    case AlarmIdRole:
        return event.alarmId;
    case MeterIdRole:
        return event.meterId;
    case MeterNameRole:
        return event.meterName;
    case AlarmTypeRole:
        return static_cast<int>(event.type);
    case TypeNameRole:
        return event.typeName;
    case ValueRole:
        return event.value;
    case ThresholdRole:
        return event.threshold;
    case TimestampRole:
        return event.timestamp;
    case ActiveRole:
        return event.active;
    case AcknowledgedRole:
        return event.acknowledged;
    case DescriptionRole:
        return event.description();
    default:
        return QVariant();
    }
}

QHash<int, QByteArray> AlarmModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[AlarmIdRole] = "alarmId";
    roles[MeterIdRole] = "meterId";
    roles[MeterNameRole] = "meterName";
    roles[AlarmTypeRole] = "alarmType";
    roles[TypeNameRole] = "typeName";
    roles[ValueRole] = "value";
    roles[ThresholdRole] = "threshold";
    roles[TimestampRole] = "timestamp";
    roles[ActiveRole] = "active";
    roles[AcknowledgedRole] = "acknowledged";
    roles[DescriptionRole] = "description";
    return roles;
}

void AlarmModel::setFilterMode(FilterMode mode)
{
    if (m_filterMode != mode)
    {
        m_filterMode = mode;
        emit filterModeChanged();
        updateFilteredAlarms();
    }
}

void AlarmModel::setShowActiveOnly(bool activeOnly)
{
    if (m_showActiveOnly != activeOnly)
    {
        m_showActiveOnly = activeOnly;
        emit showActiveOnlyChanged();
        updateFilteredAlarms();
    }
}

void AlarmModel::setFilterMeterId(int meterId)
{
    if (m_filterMeterId != meterId)
    {
        m_filterMeterId = meterId;
        updateFilteredAlarms();
    }
}

void AlarmModel::refresh()
{
    updateFilteredAlarms();
}

bool AlarmModel::acknowledgeAlarmAt(int index)
{
    if (index < 0 || index >= m_filteredAlarms.size())
    {
        return false;
    }

    AlarmEvent &event = m_filteredAlarms[index];
    if (m_alarmEngine->acknowledgeAlarm(event.alarmId))
    {
        event.acknowledged = true;

        // 通知该行数据变化
        QModelIndex modelIndex = this->index(index);
        emit dataChanged(modelIndex, modelIndex, {AcknowledgedRole});

        return true;
    }

    return false;
}

void AlarmModel::acknowledgeAllAlarms()
{
    QVector<int> alarmIds;
    for (const AlarmEvent &event : m_filteredAlarms)
    {
        if (!event.acknowledged)
        {
            alarmIds.append(event.alarmId);
        }
    }

    if (!alarmIds.isEmpty())
    {
        DBManager::instance()->batchAcknowledgeAlarms(alarmIds);

        // 更新模型中的状态
        for (int i = 0; i < m_filteredAlarms.size(); ++i)
        {
            if (!m_filteredAlarms[i].acknowledged)
            {
                m_filteredAlarms[i].acknowledged = true;
                QModelIndex modelIndex = index(i);
                emit dataChanged(modelIndex, modelIndex, {AcknowledgedRole});
            }
        }
    }
}

QVariantMap AlarmModel::getAlarmAt(int index) const
{
    if (index < 0 || index >= m_filteredAlarms.size())
    {
        return QVariantMap();
    }

    return alarmEventToVariantMap(m_filteredAlarms.at(index));
}

void AlarmModel::onAlarmTriggered(const AlarmEvent &event)
{
    // 检查是否符合过滤条件
    if (matchFilter(event))
    {
        // 插入到列表开头（最新的报警显示在最上面）
        beginInsertRows(QModelIndex(), 0, 0);
        m_filteredAlarms.prepend(event);
        endInsertRows();

        emit countChanged();
    }
}

void AlarmModel::onAlarmRecovered(int meterId, AlarmType type)
{
    // 查找并更新对应的报警
    for (int i = 0; i < m_filteredAlarms.size(); ++i)
    {
        AlarmEvent &event = m_filteredAlarms[i];
        if (event.meterId == meterId && event.type == type)
        {
            event.active = false;

            if (m_showActiveOnly)
            {
                // 如果仅显示激活的报警，则移除该项
                beginRemoveRows(QModelIndex(), i, i);
                m_filteredAlarms.removeAt(i);
                endRemoveRows();
                emit countChanged();
            }
            else
            {
                // 否则更新该行
                QModelIndex modelIndex = index(i);
                emit dataChanged(modelIndex, modelIndex, {ActiveRole});
            }

            break;
        }
    }
}

void AlarmModel::updateFilteredAlarms()
{
    beginResetModel();
    m_filteredAlarms.clear();

    if (m_alarmEngine)
    {
        if (m_showActiveOnly)
        {
            // 从报警引擎获取激活的报警
            QVector<AlarmEvent> activeAlarms = m_alarmEngine->getActiveAlarms();
            for (const AlarmEvent &event : activeAlarms)
            {
                if (matchFilter(event))
                {
                    m_filteredAlarms.append(event);
                }
            }
        }
        else
        {
            // 从数据库获取历史报警
            DBManager *db = DBManager::instance();
            if (db)
            {
                QDateTime endTime = QDateTime::currentDateTime();
                QDateTime startTime = endTime.addDays(-7); // 默认显示最近7天

                int filterMeterId = (m_filterMode == ShowByMeter) ? m_filterMeterId : -1;
                QVector<AlarmRecord> records = db->queryAlarmRecords(
                    filterMeterId, startTime, endTime);

                for (const AlarmRecord &record : records)
                {
                    AlarmEvent event;
                    event.alarmId = record.id;
                    event.meterId = record.meterId;
                    event.meterName = QString("电表-%1").arg(record.meterId); // 简化处理
                    event.typeName = record.alarmType;
                    event.value = record.alarmValue;
                    event.threshold = record.threshold;
                    event.timestamp = record.timestamp;
                    event.active = false; // 历史报警默认不激活
                    event.acknowledged = record.acknowledged;

                    // 尝试从报警类型名称推断AlarmType
                    // 这里简化处理，实际应该在数据库中存储类型枚举
                    event.type = AlarmType::DeviceOffline; // 默认值

                    if (matchFilter(event))
                    {
                        m_filteredAlarms.append(event);
                    }
                }
            }
        }

        // 按时间倒序排序（最新的在前面）
        std::sort(m_filteredAlarms.begin(), m_filteredAlarms.end(),
                  [](const AlarmEvent &a, const AlarmEvent &b)
                  {
                      return a.timestamp > b.timestamp;
                  });
    }

    endResetModel();
    emit countChanged();
}

bool AlarmModel::matchFilter(const AlarmEvent &event) const
{
    switch (m_filterMode)
    {
    case ShowAll:
        return true;

    case ShowVoltageAlarms:
        return (event.type == AlarmType::VoltageDropA ||
                event.type == AlarmType::VoltageDropB ||
                event.type == AlarmType::VoltageDropC ||
                event.type == AlarmType::OverVoltageA ||
                event.type == AlarmType::OverVoltageB ||
                event.type == AlarmType::OverVoltageC ||
                event.type == AlarmType::UnderVoltageA ||
                event.type == AlarmType::UnderVoltageB ||
                event.type == AlarmType::UnderVoltageC);

    case ShowCurrentAlarms:
        return (event.type == AlarmType::OverCurrentA ||
                event.type == AlarmType::OverCurrentB ||
                event.type == AlarmType::OverCurrentC);

    case ShowOfflineAlarms:
        return (event.type == AlarmType::DeviceOffline);

    case ShowByMeter:
        return (m_filterMeterId == -1 || event.meterId == m_filterMeterId);

    default:
        return true;
    }
}

QVariantMap AlarmModel::alarmEventToVariantMap(const AlarmEvent &event) const
{
    QVariantMap map;
    map["alarmId"] = event.alarmId;
    map["meterId"] = event.meterId;
    map["meterName"] = event.meterName;
    map["alarmType"] = static_cast<int>(event.type);
    map["typeName"] = event.typeName;
    map["value"] = event.value;
    map["threshold"] = event.threshold;
    map["timestamp"] = event.timestamp;
    map["active"] = event.active;
    map["acknowledged"] = event.acknowledged;
    map["description"] = event.description();
    return map;
}

void AlarmModel::queryHistoryAlarms(int meterId,
                                    const QString &startTime,
                                    const QString &endTime,
                                    int acknowledgedFilter,
                                    int offset,
                                    int limit)
{
    LOG_INFO(QString("查询历史报警：电表ID=%1, 时间=%2~%3, 确认状态=%4, offset=%5, limit=%6")
                 .arg(meterId)
                 .arg(startTime)
                 .arg(endTime)
                 .arg(acknowledgedFilter)
                 .arg(offset)
                 .arg(limit));

    beginResetModel();
    m_filteredAlarms.clear();

    DBManager *db = DBManager::instance();
    if (!db)
    {
        LOG_ERROR("数据库管理器未初始化");
        endResetModel();
        emit countChanged();
        return;
    }

    // 解析时间字符串
    QDateTime start = QDateTime::fromString(startTime, Qt::ISODate);
    QDateTime end = QDateTime::fromString(endTime, Qt::ISODate);

    if (!start.isValid() || !end.isValid())
    {
        LOG_ERROR(QString("时间格式无效: %1 ~ %2").arg(startTime).arg(endTime));
        endResetModel();
        emit countChanged();
        return;
    }

    // 查询数据库
    QVector<AlarmRecord> records = db->queryAlarmRecords(meterId, start, end, acknowledgedFilter);

    // 转换为AlarmEvent
    for (const AlarmRecord &record : records)
    {
        AlarmEvent event;
        event.alarmId = record.id;
        event.meterId = record.meterId;
        event.meterName = QString("电表-%1").arg(record.meterId); // 简化处理
        event.typeName = record.alarmType;
        event.value = record.alarmValue;
        event.threshold = record.threshold;
        event.timestamp = record.timestamp;
        event.active = false; // 历史报警默认不激活
        event.acknowledged = record.acknowledged;

        // 从报警类型名称推断AlarmType枚举
        event.type = parseAlarmType(record.alarmType);

        if (matchFilter(event))
        {
            m_filteredAlarms.append(event);
        }
    }

    // 按时间倒序排序
    std::sort(m_filteredAlarms.begin(), m_filteredAlarms.end(),
              [](const AlarmEvent &a, const AlarmEvent &b)
              {
                  return a.timestamp > b.timestamp;
              });

    // 应用分页
    if (offset > 0 || limit > 0)
    {
        int start = offset;
        int count = (limit > 0) ? limit : m_filteredAlarms.size();

        if (start < m_filteredAlarms.size())
        {
            QVector<AlarmEvent> pagedAlarms;
            int end = qMin(start + count, m_filteredAlarms.size());
            for (int i = start; i < end; ++i)
            {
                pagedAlarms.append(m_filteredAlarms.at(i));
            }
            m_filteredAlarms = pagedAlarms;
        }
        else
        {
            m_filteredAlarms.clear();
        }
    }

    endResetModel();
    emit countChanged();

    LOG_INFO(QString("查询完成，共 %1 条报警记录").arg(m_filteredAlarms.size()));
}

QVariantMap AlarmModel::getStatistics() const
{
    QVariantMap stats;

    int totalCount = m_filteredAlarms.size();
    int unacknowledgedCount = 0;
    int voltageCount = 0;
    int currentCount = 0;
    int offlineCount = 0;

    for (const AlarmEvent &event : m_filteredAlarms)
    {
        if (!event.acknowledged)
        {
            unacknowledgedCount++;
        }

        // 统计报警类型
        switch (event.type)
        {
        case AlarmType::VoltageDropA:
        case AlarmType::VoltageDropB:
        case AlarmType::VoltageDropC:
        case AlarmType::OverVoltageA:
        case AlarmType::OverVoltageB:
        case AlarmType::OverVoltageC:
        case AlarmType::UnderVoltageA:
        case AlarmType::UnderVoltageB:
        case AlarmType::UnderVoltageC:
            voltageCount++;
            break;

        case AlarmType::OverCurrentA:
        case AlarmType::OverCurrentB:
        case AlarmType::OverCurrentC:
            currentCount++;
            break;

        case AlarmType::DeviceOffline:
            offlineCount++;
            break;
        }
    }

    stats["totalCount"] = totalCount;
    stats["unacknowledgedCount"] = unacknowledgedCount;
    stats["voltageCount"] = voltageCount;
    stats["currentCount"] = currentCount;
    stats["offlineCount"] = offlineCount;

    return stats;
}

bool AlarmModel::exportToCSV(int meterId,
                             const QString &startTime,
                             const QString &endTime,
                             const QString &filePath)
{
    LOG_INFO(QString("导出报警记录到CSV: %1").arg(filePath));

    DBManager *db = DBManager::instance();
    if (!db)
    {
        LOG_ERROR("数据库管理器未初始化");
        return false;
    }

    // 解析时间字符串
    QDateTime start = QDateTime::fromString(startTime, Qt::ISODate);
    QDateTime end = QDateTime::fromString(endTime, Qt::ISODate);

    if (!start.isValid() || !end.isValid())
    {
        LOG_ERROR(QString("时间格式无效: %1 ~ %2").arg(startTime).arg(endTime));
        return false;
    }

    // 查询数据
    QVector<AlarmRecord> records = db->queryAlarmRecords(meterId, start, end, -1);

    if (records.isEmpty())
    {
        LOG_WARNING("没有可导出的报警记录");
        return false;
    }

    // 打开文件
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        LOG_ERROR(QString("无法打开文件: %1").arg(filePath));
        return false;
    }

    QTextStream out(&file);
    out.setCodec("UTF-8"); // 支持中文

    // 写入CSV头部（带BOM以便Excel正确识别UTF-8）
    file.write("\xEF\xBB\xBF", 3); // 直接写入UTF-8 BOM字节
    out << QString("报警ID,电表ID,电表名称,报警类型,报警值,阈值,触发时间,确认状态,确认时间\n");

    // 写入数据行
    for (const AlarmRecord &record : records)
    {
        QString meterName = QString("电表-%1").arg(record.meterId);
        QString acknowledgedStr = record.acknowledged ? "已确认" : "未确认";
        QString ackTimeStr = record.ackTime.isValid() ? record.ackTime.toString("yyyy-MM-dd HH:mm:ss") : "";

        out << QString("%1,%2,%3,%4,%5,%6,%7,%8,%9\n")
                   .arg(record.id)
                   .arg(record.meterId)
                   .arg(meterName)
                   .arg(record.alarmType)
                   .arg(record.alarmValue)
                   .arg(record.threshold)
                   .arg(record.timestamp.toString("yyyy-MM-dd HH:mm:ss"))
                   .arg(acknowledgedStr)
                   .arg(ackTimeStr);
    }

    file.close();

    LOG_INFO(QString("成功导出 %1 条报警记录到 %2").arg(records.size()).arg(filePath));
    return true;
}

int AlarmModel::batchAcknowledgeByIds(const QVariantList &alarmIds)
{
    QVector<int> ids;
    for (const QVariant &id : alarmIds)
    {
        ids.append(id.toInt());
    }

    if (ids.isEmpty())
    {
        LOG_WARNING("批量确认：报警ID列表为空");
        return 0;
    }

    DBManager *db = DBManager::instance();
    if (!db)
    {
        LOG_ERROR("数据库管理器未初始化");
        return 0;
    }

    int count = db->batchAcknowledgeAlarms(ids);

    // 更新模型中的状态
    for (int i = 0; i < m_filteredAlarms.size(); ++i)
    {
        if (ids.contains(m_filteredAlarms[i].alarmId))
        {
            m_filteredAlarms[i].acknowledged = true;
            QModelIndex modelIndex = index(i);
            emit dataChanged(modelIndex, modelIndex, {AcknowledgedRole});
        }
    }

    LOG_INFO(QString("批量确认 %1 条报警记录").arg(count));
    return count;
}

AlarmType AlarmModel::parseAlarmType(const QString &typeName) const
{
    if (typeName.contains("A相电压跌落") || typeName.contains("VoltageDropA"))
        return AlarmType::VoltageDropA;
    if (typeName.contains("B相电压跌落") || typeName.contains("VoltageDropB"))
        return AlarmType::VoltageDropB;
    if (typeName.contains("C相电压跌落") || typeName.contains("VoltageDropC"))
        return AlarmType::VoltageDropC;
    if (typeName.contains("A相过压") || typeName.contains("OverVoltageA"))
        return AlarmType::OverVoltageA;
    if (typeName.contains("B相过压") || typeName.contains("OverVoltageB"))
        return AlarmType::OverVoltageB;
    if (typeName.contains("C相过压") || typeName.contains("OverVoltageC"))
        return AlarmType::OverVoltageC;
    if (typeName.contains("A相欠压") || typeName.contains("UnderVoltageA"))
        return AlarmType::UnderVoltageA;
    if (typeName.contains("B相欠压") || typeName.contains("UnderVoltageB"))
        return AlarmType::UnderVoltageB;
    if (typeName.contains("C相欠压") || typeName.contains("UnderVoltageC"))
        return AlarmType::UnderVoltageC;
    if (typeName.contains("A相过流") || typeName.contains("OverCurrentA"))
        return AlarmType::OverCurrentA;
    if (typeName.contains("B相过流") || typeName.contains("OverCurrentB"))
        return AlarmType::OverCurrentB;
    if (typeName.contains("C相过流") || typeName.contains("OverCurrentC"))
        return AlarmType::OverCurrentC;
    if (typeName.contains("离线") || typeName.contains("Offline"))
        return AlarmType::DeviceOffline;

    return AlarmType::DeviceOffline; // 默认值
}